﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.Storage.Streams;
using System.Text.RegularExpressions;
using Windows.UI.Xaml.Media.Imaging;

namespace eLuk.CommandEngine
{
	public static class Misc
	{
		public static void Delay( int Milisecond )
		{
			int iTick = System.Environment.TickCount;
			int iTickNew = 0;
			do
			{
				iTickNew = System.Environment.TickCount;
			}
			while ( iTickNew < ( iTick + Milisecond ) );
		}

		//internal static string ReadLine( this Windows.Storage.Streams.DataReader stream, int maxLength, Encoding encoding, char? termChar )
		//{
		//	var maxLengthSpecified = maxLength > 0;
		//	int i;
		//	byte b = 0, b0;
		//	var read = false;
		//	try
		//	{
		//		using ( var mem = new MemoryStream() )
		//		{
		//			while ( true )
		//			{
		//				b0 = b;
		//				i = stream.ReadByte();
		//				if ( i == -1 )
		//					break;
		//				else
		//					read = true;

		//				b = ( byte ) i;
		//				if ( maxLengthSpecified )
		//					maxLength--;

		//				if ( maxLengthSpecified && mem.Length == 1 && b == termChar && b0 == termChar )
		//				{
		//					maxLength++;
		//					continue;
		//				}

		//				if ( b == 10 || b == 13 )
		//				{
		//					if ( mem.Length == 0 && b == 10 )
		//					{
		//						continue;
		//					}
		//					else
		//						break;
		//				}

		//				mem.WriteByte( b );
		//				if ( maxLengthSpecified && maxLength == 0 )
		//					break;
		//			}

		//			if ( mem.Length == 0 && !read )
		//				return null;
		//			return encoding.GetString( mem.ToArray(), 0, ( int ) mem.Length );
		//		}
		//	}
		//	catch ( Exception )
		//	{
		//			return null;
		//	}
		//}

		internal async static Task<string> ReadLine( this Windows.Storage.Streams.DataReader stream )
		{
			byte b = 0;
			try
			{
				using ( var mem = new MemoryStream() )
				{
					while ( true )
					{
						//b0 = b;
						b = stream.ReadByte();

						if ( b == 13 || b == 10 )
						{
							if ( mem.Length == 0 && b == 10 )
							{
								continue;
							}
							else
							{
								if ( b == 13 )
								{
									byte bn = stream.ReadByte();
									if ( bn == 10 )
									{
										mem.WriteByte( b );
										mem.WriteByte( bn );
									}
								}
								break;
							}
						}
						mem.WriteByte( b );
					}
					return System.Text.Encoding.UTF8.GetString( mem.ToArray(), 0, ( int ) mem.Length );
				}
			}
			catch ( Exception )
			{
				return null;
			}
		}

		public static string Substring( this string input, string StartDelemeter, string EndDelemeter, bool ConsiderDelemeterLength = true )
		{
			string output = "";
			int _indexStart = input.IndexOf( StartDelemeter );
			if ( ConsiderDelemeterLength )
			{
				_indexStart += StartDelemeter.Length;
			}

			int _indexEnd = input.IndexOf( EndDelemeter, _indexStart );

			try
			{
				output = input.Substring( _indexStart + 1, _indexEnd - _indexStart - 1 );
			}
			catch { }
			return output;
		}

		public static string Before( this string input, string EndDelemeter )
		{
			string lastLine = "";
			lastLine = input;
			int _indexOf = lastLine.IndexOf( EndDelemeter );
			if ( _indexOf > 0 )
				lastLine = lastLine.Substring( 0, _indexOf );
			//lastLine = lastLine;//.TrimStart( new char[] { '\r', '\n' } );
			return lastLine;
		}

		public static string LastLine( this string input )
		{
			string lastLine = "";
			lastLine = input.TrimEnd( new char[] { '\r', '\n' } );
			int _indexOf = lastLine.LastIndexOf( "\r\n" );
			if ( _indexOf > 0 )
				lastLine = lastLine.Substring( _indexOf );
			lastLine = lastLine.TrimStart( new char[] { '\r', '\n' } );
			return lastLine;
		}

		public static string FirstLine( this string input )
		{
			string lastLine = "";
			lastLine = input.TrimStart( new char[] { '\r', '\n' } );
			int _indexOf = lastLine.IndexOf( "\r\n", 0 );
			if ( _indexOf > 0 )
				lastLine = lastLine.Substring( 0, _indexOf );
			lastLine = lastLine.TrimEnd( new char[] { '\r', '\n' } );
			return lastLine;
		}

		public static string MoveToNextLine( this string input )
		{
			string lastLine = "";
			lastLine = input;
			int _indexOf = lastLine.IndexOf( "\r\n", 0 );
			if ( _indexOf > 0 )
				lastLine = lastLine.Substring( _indexOf, lastLine.Length - _indexOf );
			lastLine = lastLine.TrimStart( new char[] { '\r', '\n' } );
			return lastLine;
		}

		public static string MoveTo( this string input, string StartDelemeter, bool ConsiderDelemeterLength = true )
		{
			string lastLine = "";
			lastLine = input;
			int _indexOf = lastLine.IndexOf( StartDelemeter );
			if ( ConsiderDelemeterLength )
				_indexOf += StartDelemeter.Length;

			if ( _indexOf > 0 )
				lastLine = lastLine.Substring( _indexOf, lastLine.Length - _indexOf );
			//lastLine = lastLine;//.TrimStart( new char[] { '\r', '\n' } );
			return lastLine;
		}

		public static string DecodeQuotedPrintable(this string input, bool decodeCrLf = true)  
		{
			if ( decodeCrLf )
				input = input.Replace( "=\r\n", "" );
			var occurences = new Regex(@"(=[0-9A-Z][0-9A-Z])+", RegexOptions.Multiline);  
			var matches = occurences.Matches(input);  
			foreach (Match m in matches)  
			{  
				byte[] bytes = new byte[m.Value.Length / 3];  
				for (int i = 0; i < bytes.Length; i++)  
				{  
					string hex = m.Value.Substring(i * 3 + 1, 2);
					int iHex = Convert.ToInt32(hex, 16);  
					bytes[i] = Convert.ToByte(iHex);  
				}
				//Encoding encoding = Encoding.GetEncoding("us-ansi");
				string value = Encoding.UTF8.GetString( bytes, 0, bytes.Length );
				input = input.Replace( m.Value, value );
			}  
			return input.Replace("=rn", "");  
		}  

		public static async Task<bool> WriteFile(string Content)
		{
			StorageFolder folder = null;
			bool createFolder = false;
			bool createFile = false;
			StorageFile file = null;

			try
			{
				try
				{
					folder = await ApplicationData.Current.LocalFolder.GetFolderAsync( "eLuk" );
					createFolder = false;
				}
				catch ( Exception ex )
				{
					if ( ex is FileNotFoundException )
						createFolder = true;
				}
				if ( createFolder )
					folder = await ApplicationData.Current.LocalFolder.CreateFolderAsync( "eLuk" );

				if ( folder != null )
				{
					try
					{
						file = await folder.GetFileAsync( "imap-trace.txt" );
						createFile = false;
					}
					catch ( Exception ex )
					{
						if ( ex is FileNotFoundException )
							createFile = true;
					}
				}

				if ( createFile )
					file = await folder.CreateFileAsync( "imap-trace.txt" );

				if ( file.IsAvailable )
				{
					await FileIO.AppendTextAsync( file, Content + System.Environment.NewLine + System.Environment.NewLine );
				}
			}
			catch ( Exception ex )
			{

			}


			return true;

		}

		#region DateFormats
		public static string[] DateTimePatterns = 
		{
			"dd-MMM-yy",
			"M/d/yyyy",
			"M/d/yy",
			"MM/dd/yy",
			"MM/dd/yyyy",
			"yy/MM/dd",
			"yyyy-MM-dd",
			"dddd, MMMM dd, yyyy",
			"MMMM dd, yyyy",
			"dddd, dd MMMM, yyyy",
			"dd MMMM, yyyy",
			"dddd, MMMM dd, yyyy h:mm tt",
			"dddd, MMMM dd, yyyy hh:mm tt",
			"dddd, MMMM dd, yyyy H:mm",
			"dddd, MMMM dd, yyyy HH:mm",
			"MMMM dd, yyyy h:mm tt",
			"MMMM dd, yyyy hh:mm tt",
			"MMMM dd, yyyy H:mm",
			"MMMM dd, yyyy HH:mm",
			"dddd, dd MMMM, yyyy h:mm tt",
			"dddd, dd MMMM, yyyy hh:mm tt",
			"dddd, dd MMMM, yyyy H:mm",
			"dddd, dd MMMM, yyyy HH:mm",
			"dd MMMM, yyyy h:mm tt",
			"dd MMMM, yyyy hh:mm tt",
			"dd MMMM, yyyy H:mm",
			"dd MMMM, yyyy HH:mm",
			"dddd, MMMM dd, yyyy HH:mm:ss",
			"dddd, MMMM dd, yyyy h:mm:ss tt",
			"dddd, MMMM dd, yyyy hh:mm:ss tt",
			"dddd, MMMM dd, yyyy H:mm:ss",
			"MMMM dd, yyyy HH:mm:ss",
			"MMMM dd, yyyy h:mm:ss tt",
			"MMMM dd, yyyy hh:mm:ss tt",
			"MMMM dd, yyyy H:mm:ss",
			"dddd, dd MMMM, yyyy HH:mm:ss",
			"dddd, dd MMMM, yyyy h:mm:ss tt",
			"dddd, dd MMMM, yyyy hh:mm:ss tt",
			"dddd, dd MMMM, yyyy H:mm:ss",
			"dd MMMM, yyyy HH:mm:ss",
			"dd MMMM, yyyy h:mm:ss tt",
			"dd MMMM, yyyy hh:mm:ss tt",
			"dd MMMM, yyyy H:mm:ss",
			"dd-MMM-yy h:mm tt",
			"dd-MMM-yy hh:mm tt",
			"dd-MMM-yy H:mm",
			"dd-MMM-yy HH:mm",
			"M/d/yyyy h:mm tt",
			"M/d/yyyy hh:mm tt",
			"M/d/yyyy H:mm",
			"M/d/yyyy HH:mm",
			"M/d/yy h:mm tt",
			"M/d/yy hh:mm tt",
			"M/d/yy H:mm",
			"M/d/yy HH:mm",
			"MM/dd/yy h:mm tt",
			"MM/dd/yy hh:mm tt",
			"MM/dd/yy H:mm",
			"MM/dd/yy HH:mm",
			"MM/dd/yyyy h:mm tt",
			"MM/dd/yyyy hh:mm tt",
			"MM/dd/yyyy H:mm",
			"MM/dd/yyyy HH:mm",
			"yy/MM/dd h:mm tt",
			"yy/MM/dd hh:mm tt",
			"yy/MM/dd H:mm",
			"yy/MM/dd HH:mm",
			"yyyy-MM-dd h:mm tt",
			"yyyy-MM-dd hh:mm tt",
			"yyyy-MM-dd H:mm",
			"yyyy-MM-dd HH:mm",
			"dd-MMM-yy HH:mm:ss",
			"dd-MMM-yy h:mm:ss tt",
			"dd-MMM-yy hh:mm:ss tt",
			"dd-MMM-yy H:mm:ss",
			"M/d/yyyy HH:mm:ss",
			"M/d/yyyy h:mm:ss tt",
			"M/d/yyyy hh:mm:ss tt",
			"M/d/yyyy H:mm:ss",
			"M/d/yy HH:mm:ss",
			"M/d/yy h:mm:ss tt",
			"M/d/yy hh:mm:ss tt",
			"M/d/yy H:mm:ss",
			"MM/dd/yy HH:mm:ss",
			"MM/dd/yy h:mm:ss tt",
			"MM/dd/yy hh:mm:ss tt",
			"MM/dd/yy H:mm:ss",
			"MM/dd/yyyy HH:mm:ss",
			"MM/dd/yyyy h:mm:ss tt",
			"MM/dd/yyyy hh:mm:ss tt",
			"MM/dd/yyyy H:mm:ss",
			"yy/MM/dd HH:mm:ss",
			"yy/MM/dd h:mm:ss tt",
			"yy/MM/dd hh:mm:ss tt",
			"yy/MM/dd H:mm:ss",
			"yyyy-MM-dd HH:mm:ss",
			"yyyy-MM-dd h:mm:ss tt",
			"yyyy-MM-dd hh:mm:ss tt",
			"yyyy-MM-dd H:mm:ss",
			"MMMM dd",
			"MMMM dd",
			"yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffffffK",
			"yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffffffK",
			"ddd, dd MMM yyyy HH':'mm':'ss 'GMT'",
			"ddd, dd MMM yyyy HH':'mm':'ss 'GMT'",
			"yyyy'-'MM'-'dd'T'HH':'mm':'ss",
			"h:mm tt",
			"hh:mm tt",
			"H:mm",
			"HH:mm",
			"HH:mm:ss",
			"h:mm:ss tt",
			"hh:mm:ss tt",
			"H:mm:ss",
			"yyyy'-'MM'-'dd HH':'mm':'ss'Z'",
			"dddd, MMMM dd, yyyy HH:mm:ss",
			"dddd, MMMM dd, yyyy h:mm:ss tt",
			"dddd, MMMM dd, yyyy hh:mm:ss tt",
			"dddd, MMMM dd, yyyy H:mm:ss",
			"MMMM dd, yyyy HH:mm:ss",
			"MMMM dd, yyyy h:mm:ss tt",
			"MMMM dd, yyyy hh:mm:ss tt",
			"MMMM dd, yyyy H:mm:ss",
			"dddd, dd MMMM, yyyy HH:mm:ss",
			"dddd, dd MMMM, yyyy h:mm:ss tt",
			"dddd, dd MMMM, yyyy hh:mm:ss tt",
			"dddd, dd MMMM, yyyy H:mm:ss",
			"dd MMMM, yyyy HH:mm:ss",
			"dd MMMM, yyyy h:mm:ss tt",
			"dd MMMM, yyyy hh:mm:ss tt",
			"dd MMMM, yyyy H:mm:ss",
			"MMMM, yyyy",
			"MMMM, yyyy",
			"ddd',' dd MMM yyyy HH':'mm':'ss'.'fffffff zzzz",
			"ddd',' dd MMM yyyy HH':'mm':'ss'.'ffffff zzzz",
			"ddd',' dd MMM yyyy HH':'mm':'ss'.'fffff zzzz",
			"ddd',' dd MMM yyyy HH':'mm':'ss'.'ffff zzzz",
			"ddd',' dd MMM yyyy HH':'mm':'ss'.'fff zzzz",
			"ddd',' dd MMM yyyy HH':'mm':'ss'.'ff zzzz",
			"ddd',' dd MMM yyyy HH':'mm':'ss'.'f zzzz",
			"ddd',' dd MMM yyyy HH':'mm':'ss zzzz",
			"ddd',' dd MMM yy HH':'mm':'ss'.'fffffff zzzz",
			"ddd',' dd MMM yy HH':'mm':'ss'.'ffffff zzzz",
			"ddd',' dd MMM yy HH':'mm':'ss'.'fffff zzzz",
			"ddd',' dd MMM yy HH':'mm':'ss'.'ffff zzzz",
			"ddd',' dd MMM yy HH':'mm':'ss'.'fff zzzz",
			"ddd',' dd MMM yy HH':'mm':'ss'.'ff zzzz",
			"ddd',' dd MMM yy HH':'mm':'ss'.'f zzzz",
			"ddd',' dd MMM yy HH':'mm':'ss zzzz",
			"ddd',' d MMM yyyy HH':'mm':'ss'.'fffffff zzzz",
			"ddd',' d MMM yyyy HH':'mm':'ss'.'ffffff zzzz",
			"ddd',' d MMM yyyy HH':'mm':'ss'.'fffff zzzz",
			"ddd',' d MMM yyyy HH':'mm':'ss'.'ffff zzzz",
			"ddd',' d MMM yyyy HH':'mm':'ss'.'fff zzzz",
			"ddd',' d MMM yyyy HH':'mm':'ss'.'ff zzzz",
			"ddd',' d MMM yyyy HH':'mm':'ss'.'f zzzz",
			"ddd',' d MMM yyyy HH':'mm':'ss zzzz",
			"ddd',' d MMM yy HH':'mm':'ss'.'fffffff zzzz",
			"ddd',' d MMM yy HH':'mm':'ss'.'ffffff zzzz",
			"ddd',' d MMM yy HH':'mm':'ss'.'fffff zzzz",
			"ddd',' d MMM yy HH':'mm':'ss'.'ffff zzzz",
			"ddd',' d MMM yy HH':'mm':'ss'.'fff zzzz",
			"ddd',' d MMM yy HH':'mm':'ss'.'ff zzzz",
			"ddd',' d MMM yy HH':'mm':'ss'.'f zzzz",
			"ddd',' d MMM yy HH':'mm':'ss zzzz",
			"yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffffK"
		};
		#endregion DateFormats
	}
}
